import numpy as np
from sklearn.random_projection import GaussianRandomProjection
from sklearn.metrics.pairwise import euclidean_distances
from sklearn.neighbors import NearestNeighbors

# 1. 数据生成
np.random.seed(42)
num_points = 1000  # 数据点数量
high_dim = 100     # 高维空间维度
low_dim = 10       # 降维后的目标维度

# 生成高维数据点
data_high_dim = np.random.rand(num_points, high_dim)
# 模拟查询点
query_point_high_dim = np.random.rand(1, high_dim)

# 2. 随机投影降维
# 使用高斯随机投影降维
transformer = GaussianRandomProjection(
    n_components=low_dim, random_state=42)
data_low_dim = transformer.fit_transform(data_high_dim)
query_point_low_dim = transformer.transform(query_point_high_dim)

# 3. 原始空间中的最近邻检索
nbrs_high = NearestNeighbors(
    n_neighbors=5, metric='euclidean').fit(data_high_dim)
distances_high, indices_high = nbrs_high.kneighbors(query_point_high_dim)

# 4. 降维空间中的最近邻检索
nbrs_low = NearestNeighbors(
    n_neighbors=5, metric='euclidean').fit(data_low_dim)
distances_low, indices_low = nbrs_low.kneighbors(query_point_low_dim)

# 5. 结果对比与输出
print("查询点（高维空间）:", query_point_high_dim[0])
print("\n原始高维空间中最近的5个点:")
for i, (index, distance) in enumerate(
    zip(indices_high[0], distances_high[0])):
    print(f"结果 {i + 1}: 索引 {index}, 距离 {distance:.4f}")

print("\n降维后低维空间中最近的5个点:")
for i, (index, distance) in enumerate(zip(indices_low[0], distances_low[0])):
    print(f"结果 {i + 1}: 索引 {index}, 距离 {distance:.4f}")

# 6. 距离对比分析
# 对比高维和低维空间中查询点到最近邻的平均距离
avg_distance_high = np.mean(distances_high[0])
avg_distance_low = np.mean(distances_low[0])

print("\n距离对比:")
print(f"高维空间中查询点到最近邻的平均距离: {avg_distance_high:.4f}")
print(f"低维空间中查询点到最近邻的平均距离: {avg_distance_low:.4f}")